<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*
      1. 简单的语法
      ● const 与 let
        特点：没有变量提升，不能重复声明，产生块级作用域
        严格来说：变量有提升，但是在到达变量定义之前不能访问，访问报错

      ● 解构赋值
      ● 形参默认值
      ● 扩展运算符: ...
      ● 模板字符串
      ● 对象的属性与方法简写
      ● 模块化语法 import export
      ● Symbol 新的基本数据类型
      ● ...
      2. 比较复杂的语法
      ● 箭头函数（引申总结 this 指向）
        - 箭头函数和普通函数区别
        - 总结 this 指向
      ● class 与 extend（引申原型和继承）
        - 总结所有继承方法
      ● promise / generator / async & await（引申 js 事件循环机制）
        - promise + async & await 异步编程最终方案
        - 都属于微任务 -  js 事件循环机制
      ● Proxy（引申 vue2 和 vue3 响应式原理）
        - vue2是通过Object.defineProperty实现的响应式，问题是新增数据不是响应式的
        - vue3是通过Proxy实现的响应式，解决了这个问题
      ● Map / Set / WeakMap / WeakSet (引申 vue3 响应式原理)
        Map相当于对象，存储键值对，特点：key可以是任意类型
        Set相当于数组，特点：值是唯一的   数组去重：[...new Set(arr)]
        WeakMap和Map相似，有两点不同：1. WeakMap的key只能是对象类型 2. 一旦key对应的对象，外面没有引用，整个数据被垃圾回收机制回收
        WeakSet和Set相似，有两点不同：1. WeakSet的值只能是对象类型 2. 一旦值对应的对象，外面没有引用，整个数据被垃圾回收机制回收
      ● ...
    */

      // if (true) {
      //   debugger;
      //   // https://tc39.es/ecma262/#sec-declarations-and-the-variable-statement
      //   // 暂存性死区
      //   console.log(a); // 报错：Uncaught ReferenceError: Cannot access 'a' before initialization
      //   const a = 1;
      // }

      const map = new Map();
      map.set(true, 111);
      map.set({ name: "jack" }, [111, 222]);
      console.log(map);

      const weakmap = new WeakMap();
      // weakmap.set(true, 111); // 报错
      weakmap.set({ name: "jack" }, [111, 222]);
      const obj = { age: 18 };
      weakmap.set(obj, [111, 222]);
      console.log(weakmap);
    </script>
  </body>
</html>
